package com.sina.interfaces.manage.service.user;

import com.sina.interfaces.core.exception.client.DataException;
import com.sina.interfaces.core.exception.server.CreateException;
import com.sina.interfaces.core.exception.server.ResourceExistsException;
import com.sina.interfaces.core.exception.server.UpdateException;
import com.sina.interfaces.core.util.Assert;
import com.sina.interfaces.core.util.ResultCode;
import com.sina.interfaces.core.util.StringUtils;
import com.sina.interfaces.domain.user.User;
import com.sina.interfaces.manage.dao.user.UserManageDao;
import com.sina.interfaces.service.InterFacesDataSourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

import static com.sina.interfaces.service.ServiceConstant.INTERFACE_TX;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * 段浩杰   2017-11-14-13:23
 */
@Service("userManageService")
public class UserManageServiceImpl extends InterFacesDataSourceService implements UserManageService {


    @Autowired
    @Qualifier("userManageDao")
    private UserManageDao userManageDao;

    @Override
    @Transactional(value = INTERFACE_TX, readOnly = true, isolation = Isolation.READ_COMMITTED)
    public User getUser(String name) {
        return userManageDao.getUser(name);
    }

    @Override
    @Transactional(value = INTERFACE_TX, isolation = Isolation.READ_COMMITTED)
    public int delete(Long id) throws DataException, UpdateException {

        User user = userManageDao.get(User.class, id);
        Assert.assertNotNull(user, "User[id=%s] not exists", user.getId());

        try {
            return userManageDao.delete(id);
        } catch (DataAccessException e) {
            LOG.error(" {} delete User error.", User.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }
    }

    @Override
    @Transactional(value = INTERFACE_TX, isolation = Isolation.REPEATABLE_READ)
    public User updateUser(User user) throws DataException, UpdateException {

        User u = userManageDao.get(User.class, user.getId());
        Assert.assertNotNull(u, "User[id=%s] not exists", user.getId());

        try {
            u = updateUserFiled(user, u);
            userManageDao.flush();

            return u;
        } catch (DataAccessException e) {
            LOG.error(" {} update User error.", User.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }
    }

    /**
     * 所需要更新的字段的转换
     *
     * @param oldUser 前台传来的user（瞬时态）
     * @param newUser 从数据库中查询的user（持久态）
     * @return user   最后要变为的user（执行完update后变为游离态）
     */
    private User updateUserFiled(User oldUser, User newUser) {

        if (!StringUtils.isEmpty(oldUser.getName())) {
            newUser.setName(oldUser.getName());
        }
        if (!StringUtils.isEmpty(oldUser.getLastIp())) {
            newUser.setLastIp(oldUser.getLastIp());
        }
        if (!StringUtils.isEmpty(oldUser.getEmail())) {
            newUser.setEmail(oldUser.getEmail());
        }
        if (!StringUtils.isEmpty(oldUser.getPhone())) {
            newUser.setPhone(oldUser.getPhone());
        }
        if (!StringUtils.isEmpty(oldUser.getStatus())) {
            newUser.setStatus(oldUser.getStatus());
        }
       /* if (!StringUtils.isEmpty(oldUser.getUserSex())) {
            newUser.setUserSex(oldUser.getUserSex());
        }*/

        return newUser;
    }

    @Override
    @Transactional(value = INTERFACE_TX, isolation = Isolation.READ_COMMITTED)
    public User saveUser(User user) throws CreateException, ResourceExistsException, DataException {
        boolean exists;
        exists = userManageDao.isExistsByUnique(User.class, "name", user.getName());
        Assert.assertFalse(exists, ResourceExistsException.class, ResultCode.dataExists
                , "User[%s] exists", user.getName());

        try {
            userManageDao.save(user);
            userManageDao.flush();
            return user;
        } catch (DataAccessException e) {
            LOG.error(" {} save User error.", User.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }
    }

    @Override
    @Transactional(value = INTERFACE_TX, readOnly = true, isolation = Isolation.READ_COMMITTED)
    public List<Map<String, Object>> getUserList(User user, Long[] count) {

        if (count != null && count.length > 0) {
            count[0] = userManageDao.getUserCount(user);
        }

        return userManageDao.getUserList(user);
    }
}
